TechNote - Styles

Thursday, February 16, 2023

12:52 PM

This is a discussion of font styles as they pertain to the desktop edition of OneNote.

 

First, a couple of definitions for clarity. I try to hold true to these definitions throughout the article.

 

  • An attribute always refers to an attribute of an XML element.
  • A property always refers to the individual properties of a style.

 

In this following example, a span element has a style attribute and that attribute includes a number of style properties, specifically font-style and color.

 

<span style='font-style:italic;color:#C55A11'>

 

What is the Page XML Model?

The OneNote user interface presents and lets you manage a logical view of objects known as notebooks, sections, and pages. (Section groups are really those just logical folders within a section.) Thre phyisical storage model is slightly different: a new section.one file is maintained for each section and that section.one file contains data for all pages in that section. Similarly, a new notebook.onetoc2 file is maintained for each notebook and that notebook.onetoc2 file constains an index of all sections in that notebook.

 

The section.one files are binary files with a complicated object model defined here. While it is possible to write a program to read and write these files directly, that becomes problematic when these files are stored on OneDrive where they're not so easily accessible.

 

So instead, Microsoft developed a public library (a DLL) that allows third-parties to develop add-ins for OneNote. (In fact, there are libraries for every Office product and their corresponding add-ins.) And instead of exposing the binary object models stored in the .one files, the library transforms those models into a logical XML representation to make it more readily consumable by most common programming frameworks. This XML is fully described by the OneNote Application XSD schema definition file.

 

We'll explore the logical XML representation of a page; we will not touch upon the physical storage model at all. But it's important to remember that the XML is not how the page is actually stored - it is just a representation or transformation or projection of the physical models and may not map one-to-one to how those physical models are stored.

 

Page XML

Here is the smallest possible XML representation of a OneNote page as returned by the IApplication.GetPageContent method. This does not have a one:Title block because it was created as a QuickNote, and all extraneous attributes have been removed, both for simplicity.

 

As we explore how OneNote applies styles to a page, we'll  keep track of the changes in the two areas outlined below.

 

<one:Page>

  <one:QuickStyleDef

    index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri"

    fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0" />

  <one:PageSettings RTL="false" color="#FFFFFF">

    <one:PageSize>

      <one:Automatic />

    </one:PageSize>

    <one:RuleLines visible="false" />

  </one:PageSettings>

  <one:Outline>

    <one:Position x="36.0" y="32.39999771118164" z="0" />

    <one:Size width="162.1652679443359" height="13.48873901367187" />

    <one:OEChildren>

      <one:OE alignment="left" quickStyleIndex="0">

        <one:T><![CDATA[Lorem ipsum dolor sit amet]]></one:T>

      </one:OE>

    </one:OEChildren>

  </one:Outline>

</one:Page>

 

To peek ahead just a little in discussion… what are we looking at above? The page is described by a containing one:Page element. The one:QuickStyleDef element describes the one style used on the page; note its index, 0. This is followed by a one:PageSettings element that describes the size and rule lines. And then there is a one:Outline that represents the first text "container" on the page. This container has one paragraph, a one:OE, which references quick style index 0. And that paragraph has one text run, a one:T. That text run has the string "Lorem ipsum dolor sit amet".

 

Styles

OneNote has a set of eleven standard built-in styles that can be applied to text on a page. These are listed in the Styles gallery in the Home ribbon tab

 

OneNote Styles

How they appear on a page

 

 

Heading1

Heading2

Heading3

Heading4

Heading5
Heading6

Page Title

Citation

Quote

Code

Normal

 

These are static definitions, hard-coded in OneNote itself, and cannot be altered in any way. But let's explore how these are applied to text on a page. When a style is applied to text, OneNote will ensure that the style is defined in the XML by adding a corresponding one:QuickStyleDef element that describes that style.

 

πŸ›ˆ

Paragraph Styles

It's important to note that all of the built-in styles are paragraph styles. That is, they apply to an entire paragraph. By contract, Microsoft Word has the concept of both paragraph styles and character styles, where the latter can be applied to a sequence of characters within a paragraph without necessarily affecting the entire paragraph. OneMore My Styles lets you define both paragraph styles and characters styles.

 

 

──────────────────────────────────────────────────────────────────────────────────────────────────

Exploration

Let's start with a simple example. If we were to add a Heading 1 line to this page:

 

This is a "Heading 1" line

 

OneNote first adds the following defintion if not already there. Note the value of the index attribute.

 

<one:QuickStyleDef index="2" name="h1" fontColor="#1E4E79" highlightColor="automatic" font="Calibri" fontSize="16.0" spaceBefore="0.0" spaceAfter="0.0" />

 

OneNote then links this style to a paragraph by applying its index value to the the quickStyleIndex attribute as shown here.

 

<one:OE alignment="left" quickStyleIndex="2">

  <one:T><![CDATA[This is a &quot;Heading 1&quot; line]]></one:T>

</one:OE>

 

Now, what happens if we change the color of that heading using the Basic Text Font Color button on the ribbon?

 

This is a "Heading 1" line

 

This is the result in the XML

 

<one:OE alignment="left" quickStyleIndex="2"

  style="font-family:Calibri;font-size:16.0pt;color:#C55A11">

  <one:T><![CDATA[This is a &quot;Heading 1&quot; line]]></one:T>

</one:OE>

 

Notice that the quickStyleIndex is still set to "2" but a style attribute has been added. Also, this style attribute not only includes the color override (#C55A11) but also duplicates the font-family and font-size. It's unclear why Microsoft duplicates these properties in the style attribute; I do not know if it's stored this way in the binary format or it's just projected this way in the XML for clarity or convenience for consumers. But let's explore what happens if you change part of the line

 

This is a "Heading 1" line

 

This is the result in the XML

 

<one:OE alignment="left" quickStyleIndex="2">

   <one:T><![CDATA[<span style='color:#C55A11'>This is a &quot;</span><span style='color:#70AD47'>Heading 1</span><span style='color:#C55A11'>&quot; line</span>]]></one:T>

</one:OE>

 

While the CDATA part appears to be a bit more complicated, we can easily break it down. CDATA contains a (very small) subset of HTML and CSS. In fact, that subset includes the span element and a limited set of styles that affect the font. So let's pull out the CDATA and look at it as if it were standalone XML.

 

<span style='color:#C55A11'>This is a &quot;</span>

<span style='color:#70AD47'>Heading 1</span>

<span style='color:#C55A11'>&quot; line</span>

 

The paragraph still has only one text run but that run is divided into separate spans. OneNote breaks it up to apply the explicit colors needed to override the implicit color of the Quick Style.

 

If we were to revert to the default color and then color only the "Heading 1" part, this is the result

 

This is a &quot;<span style='color:#70AD47'>Heading 1</span>&quot; line

 

So OneNote normalizes as much as it can, keeping only what's needed to express the desired result.

 

πŸ““

Styles properties are applied in this order, each overriding the previous

  • QuickStyleDef
  • one:OE style attribute
  • CDATA span style attribute

 

Now let's change the color of the entire line but italicize part of it.

 

This is a "Heading 1" line

 

Here's the XML

 

<one:OE alignment="left" quickStyleIndex="2"

  style="font-family:Calibri;font-size:16.0pt;color:#C55A11">

  <one:T><![CDATA[This is a &quot;<span style='font-style:italic'>Heading 1</span>&quot; line]]></one:T>

</one:OE>

 

Note that the font-family, font-size, and color are applied to the one:OE element, while font-style:italic is applied in a span in the CDATA.

 

πŸ““

Rules

  • Font family, size, and color may be in a span.
  • Font family, size, and color prefer to be in the one:OE
  • Bold, italic, underline, super, sub, color, and highlight will always be added to a span

 

 

Normalization and Promotion

As mentioned previously, OneNote does its best to normalize styles, promoting them upwards from a CDATA span to its parent OE - other than the noted rule exceptions above.

 

If you were to programmaticaly alter the XML or use the OneMore XML Dialog to alter the XML, you can add font family, size, and color to a CDATA span. When the page is saved, OneNote will normalize that, if it can, promoting those properties to the one:OE style attribute.

 

 

The Challenge of Complex Patterns

Consider this line of text

 

This line has multiple overlapping styles

 

Notice that there are overlapping styles, for example, the word "multiple" is styled two different ways: the first half is italic and highlighted, while the second half is italic and blue.

 

Its XML looks like this

 

<one:OE alignment="left" quickStyleIndex="1">

  <one:T><![CDATA[This <span style='text-decoration:underline'>line </span><span style='text-decoration: underline;background:yellow;mso-highlight:yellow'>has </span><span style='font-style:italic;background:yellow;mso-highlight:yellow'>mu</span><span style='font-style:italic'>l</span><span style='font-style:italic;color:#5B9BD5'>tiple</span><span style='color:#5B9BD5'> over</span>lapping styles]]></one:T>

</one:OE>

 

Break down the CDATA into

 

This <span style='text-decoration:underline'>line </span>

<span style='text-decoration: underline;background:yellow;mso-highlight:yellow'>has </span>

<span style='font-style:italic;background:yellow;mso-highlight:yellow'>mu</span>

<span style='font-style:italic'>l</span><span style='font-style:italic;color:#5B9BD5'>tiple</span>

<span style='color:#5B9BD5'> over</span>lapping styles

 

This exemplifies the challenges of searching for the word "multiple" on the page, or applying custom styles to this paragraph.

 

 

Inconsistencies

There are times when OneNote loses its mind. While it certainly attempts to normalize as much as it can, it will, at unpredictable times, duplicate a Quick Style. While writing up this page, OneNote has added these duplicate definitions to the page.

 

<one:QuickStyleDef index="1" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.5" spaceBefore="0.0" spaceAfter="0.0" />

<one:QuickStyleDef index="11" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.5" spaceBefore="0.0" spaceAfter="0.0" />

 

and

 

<one:QuickStyleDef index="2" name="h1" fontColor="#1E4E79" highlightColor="automatic" font="Calibri" fontSize="16.0" spaceBefore="0.0" spaceAfter="0.0" />

<one:QuickStyleDef index="12" name="h1" fontColor="#1E4E79" highlightColor="automatic" font="Calibri" fontSize="16.0" spaceBefore="0.0" spaceAfter="0.0" />

 

The definitions are the same, varying only by their index attributes. Why were they duplicated? Is this a bug? Who knows?

 

 

─────────────────────────────────────────────────────────────────────────────────────────────────

OneMore Styles

OneMore piggybacks on this basic OneNote style framework to implement the My Styles features. Since OneNote gracefully allows multiple Quick Style definitions with the same name, OneMore takes advantage of this to define its own styles.

 

When you create a new style, you can choose whether it is a paragraph style, a character style, or a heading. OneMore uses this information to generate an appropriate Quick Style definition.

 

When a new heading style is created and reordered, OneMore can use this information to generate a Quick Style with the appropriate h1..h6 name. By reusing the standard h1..h6 internal names, this makes it easy for OneMore to generate a table of contents for the page based on both standard headings and custom headings.

 

All other custom styles are represented by a new "p" Quick Style.

 

OneMore abides by the OneNote rules, attempting to apply and distribute styles in a normalized fashion, from CDATA to OE to QuickStyleDef.

 

However, there are times when OneMore does take advantage of the fact that OneNote will automatically normalize and reshuffle style properties when you save a page. So OneMore may dump styles into a span, even though they should go in the parent one:OE, knowing that OneNote will sort it out accordingly. These cases are rare but are often done to keep the OneMore code simple (or "simpler").

 

#omwiki #omdeveloper #omtechnote

 

Β© 2020 Steven M Cohn. All rights reserved.

Please consider a sponsorship or one-time donation to support ongoing development

 

Created with OneNote.